/*****************************************************************
IIITB MTech 1st semester Data Management project.
A simple Virtual File System.

This creates a binary blob in the persistent store.
- SEEK_SET sets the file pointer to the first byte of the file
- Move the pointer the required offset using fseek
- Append a EOF to the end (just in case) !
*****************************************************************/

#ifndef STANDARD_IO
#define STANDARD_IO

#include<stdio.h>

#endif

#ifndef STANDARD_LIB
#define STANDARD_LIB

#include<stdlib.h>

#endif

#ifndef STRING_LIB
#define STRING_LIB

#include<string.h>
#include "../include/string_operations.h"

#endif

#include"../include/global_header.h"
#include"../include/bst.h"

// #define BLOCK_SIZE 1024 * 10

void build_dir_struct() {

    root_dir = (nary_pointer)initialize_nary();
    bst_root = (bst_node_ptr)initialize_bst();
}

int file_exists(char* file_name){

    FILE* file = fopen(file_name, "r");
    if(file != NULL){
        fclose(file);
        return 1;
    }
    else{
        return 0;
    }
}

void create_vfs(char *name, int size) {

    if(file_exists(name) == 1){
        printf("%s\n",ERR_VFS_CREATE_01);       // DATA_FILE_ALREADY_EXISTS
        return;
    }

	FILE *temp_vfs_ptr = fopen(name,"w");

    if(temp_vfs_ptr == NULL){
        printf("%s\n", ERR_VFS_CREATE_02);      // CANNOT_CREATE_DATAFILE
        return;
    }

	make_free_list(size);
	make_fd_array();

	fseek(temp_vfs_ptr, 0, SEEK_SET);
    fwrite(&size, sizeof(long int), 1, temp_vfs_ptr);
	fwrite(free_list, (sizeof(char) * size * 1024) / BLOCK_SIZE, 1, temp_vfs_ptr);
    fwrite(fd_array, (sizeof(struct fd) * size * 1024) / BLOCK_SIZE, 1, temp_vfs_ptr);

    // made this SEEK_CUR from SEEK_SET because for small sizes the meta data becomes more than the actual file size
    fseek(temp_vfs_ptr, size * 1024, SEEK_CUR);
	fputc(EOF, temp_vfs_ptr);
    if(temp_vfs_ptr != NULL) fclose(temp_vfs_ptr);

    printf("%s\n", SUCC_VFS_CREATE);		// "createvfs_SUCCESS"
}

void add_file(char *file_name, char *parent_path, char *external_file, long int block_no) {

    if(total_fdcount == (total_size * 1024)/BLOCK_SIZE) {
        printf("%s\n",  ERR_VFS_ADDFILE_04);        // FILE_SYSTEM_FULL
        return;
    }

    if(file_exists(external_file) != 1){
        printf("%s\n", ERR_VFS_ADDFILE_05);         // CANNOT_WRITE_TO_DATA_FILE
        return;
    }

    FILE *fp = fopen(external_file,"r");
    FILE *binary_vfs_ptr = fopen(vfs_name,"r+");

    char temp_parent_path[256];
    strcpy(temp_parent_path,parent_path);
    nary_pointer exists = (nary_pointer) nary_search(strcat(strcat(temp_parent_path,"/"),file_name));
    if(exists != NULL) {
        printf("%s\n", ERR_VFS_ADDFILE_03);     // FILE_ALREADY_EXISTS
        return;
    }

    fseek(fp, 0, SEEK_END);
    int size = ftell(fp)-1;
    if(size >= BLOCK_SIZE) {
        printf("%s\n", ERR_VFS_ADDFILE_06);     // FILE_TOO_LARGE
        return;
    }

    char* full_path = (char*)malloc(sizeof(char)*256);

    full_path = strcpy(full_path, "root");
    full_path = strcat(full_path, parent_path);
    int len = strlen(full_path);

    if(full_path[len - 1] != '/'){
        full_path = strcat(full_path, "/");
    }

    full_path = strcat(full_path, file_name);

    if(root_dir == NULL || bst_root == NULL){
        printf("%s\n", ERR_VFS_MAKEDIR_01);
        return;
    }

	char *pp = (char *)malloc(sizeof(char) * 256);
	strcpy(pp, parent_path);
	strcat(pp, file_name);
    nary_pointer temp = nary_search(pp);
    if(temp != NULL){
    	printf("%s\n", ERR_VFS_ADDFILE_05);	// cannot write to data file
    	return;
    }
    
    int bst_res = insert_bst(full_path);

    if(bst_res == 0){ // Duplicate file/folder.
       printf("%s\n", ERR_VFS_ADDFILE_03);
       return;
    }
    else if(bst_res == -1){
       printf("%s\n",ERR_VFS_ADDFILE_04);      // "FILE_SYSTEM_FULL"
       return;
    }

	if(parent_path[strlen(parent_path)-1] != '/') strcat(parent_path,"/");
    int res = InsertIntoNArray(strcat(parent_path,file_name), file_name, block_no, 'f');

    // // getchar();
    if(res == -1){
         printf("%s\n",ERR_VFS_ADDFILE_04);      // "FILE_SYSTEM_FULL"
        return;
    }

    if(res == 0){
        printf("%s\n", ERR_VFS_ADDFILE_03);
        return;
    }

    fseek(binary_vfs_ptr, ((total_size * 1024 * sizeof(char)) / BLOCK_SIZE) +
          ((total_size * 1024 * sizeof(struct fd)) / BLOCK_SIZE) + sizeof(long int), SEEK_SET);
    fseek(binary_vfs_ptr, block_no * BLOCK_SIZE, SEEK_CUR);

    fseek(fp, 0, SEEK_SET);

    fwrite(&size, sizeof(long int), 1, binary_vfs_ptr);
    unsigned char ch;
    while(size-- != 0) {
        ch = getc(fp);
        putc(ch,binary_vfs_ptr);
    }

    if(fp != NULL) fclose(fp);

    if(binary_vfs_ptr != NULL) fclose(binary_vfs_ptr);
    
    printf("%s\n",SUCC_VFS_ADDFILE);			  // "addfile_SUCCESS"
}

void write_to_file(long int block_no, char *parent_path, char *file_name, char *string, char type) {

    int i = 0, bst_res, len;

    char *temp_path = (char *)malloc(sizeof(char) * 256);
    strcpy(temp_path,parent_path);
    if(parent_path[strlen(parent_path)-1] != '/') {
        temp_path = strcat(temp_path,"/");
    }
    temp_path = strcat(temp_path,file_name);

    char *temp_full_path = (char *)malloc(sizeof(char) * 256);
    strcpy(temp_full_path, temp_path);

    nary_pointer temp = nary_search(temp_path);

    if(temp != NULL) {
        printf("%s\n", ERR_VFS_MAKEDIR_03 );        //DIRECTORY_ALREADY_EXISTS
        return;
    }

	// New code for bst
    char* full_path = (char*)malloc(sizeof(char)*256);

    full_path = strcpy(full_path, "root");
    full_path = strcat(full_path, parent_path);
    int path_len = strlen(full_path);

    if(full_path[path_len - 1] != '/'){
        full_path = strcat(full_path, "/");
    }

    full_path = strcat(full_path, file_name);
    
    bst_res = insert_bst(full_path);

    if(bst_res == 0){ // Duplicate file/folder.
       printf("%s\n", ERR_VFS_MAKEDIR_03 );        // DIRECTORY_ALREADY_EXISTS
       return;
    }
    else if(bst_res == -1){
       printf("%s\n",ERR_VFS_MAKEDIR_01);	      	  // "FILE_SYSTEM_FULL"
       return;
    }
    
    // ends

    int res = InsertIntoNArray(temp_full_path, file_name, block_no, type);

    // // getchar();
    if(res == -1){
        printf("%s\n", ERR_VFS_MAKEDIR_01);			// "FILESYSTEM_FULL"
        return;
    }

    if(res == 0){
        printf("%s\n", ERR_VFS_MAKEDIR_03);			// "DIRECTORY_ALREADY_EXISTS"
        return;
    }

    if(type == 'f') {
        // size of total_size
        fseek(vfs_ptr, ((total_size * 1024 * sizeof(char)) / BLOCK_SIZE) +
              ((total_size * 1024 * sizeof(struct fd)) / BLOCK_SIZE) + sizeof(long int), SEEK_SET);
        int a = fseek(vfs_ptr, block_no * BLOCK_SIZE, SEEK_CUR);
        int b = fwrite(string, strlen(string), 1, vfs_ptr);
        int c = putc('\0',vfs_ptr);

        int counter = strlen(string);
        while(counter < BLOCK_SIZE) {
            putc('\0',vfs_ptr);
            counter++;
        }
    }

    printf("%s\n",SUCC_VFS_MAKEDIR);				// "makedir_SUCCESS"
}

void update_file(char *file_path, char *data) {
    nary_pointer node = (nary_pointer) nary_search(file_path);
    if(node == NULL) {
        printf("%s\n",ERR_VFS_UPDATEFILE_01); // "INTERNAL_FILE_NOT_FOUND"
        return;
    }
    long int block = node->block_num;
    fseek(vfs_ptr, sizeof(long int) + ((total_size * 1024 * sizeof(char)) / BLOCK_SIZE) +
          ((total_size * 1024 * sizeof(struct fd)) / BLOCK_SIZE), SEEK_SET);
	fseek(vfs_ptr, node->block_num * BLOCK_SIZE, SEEK_CUR);

	char ch;

    int size;
    fread(&size, sizeof(int), 1, vfs_ptr);
    FILE *fp = fopen(data,"r");
    if(ferror(fp) != 0) {
        printf("%s\n",ERR_VFS_UPDATEFILE_02); // "EXTERNAL_FILE_NOT_FOUND"
        return;
    }

    fseek(fp,0,SEEK_END);
    int append_size = ftell(fp)-1;

    if(size + append_size >= BLOCK_SIZE) {
        printf("%s\n",ERR_VFS_UPDATEFILE_03); // "EXTERNAL_FILE_TOO_LARGE"
        return;
    }


    size += append_size;

    fseek(vfs_ptr,-sizeof(int),SEEK_CUR);
    fwrite(&size,sizeof(int),1,vfs_ptr);

    fseek(fp,0,SEEK_SET);
    fseek(vfs_ptr,size,SEEK_CUR);
    while((ch = getc(fp)) != EOF) {
        putc(ch,vfs_ptr);
    }

    if(fp != NULL) fclose(fp);
    printf("%s\n",SUCC_VFS_UPDATEFILE);			// "updatefile_SUCCESS"
}

void copy_file(char *input_path, char *output_path) {
    unsigned char ch;
    char input_copy[256], output_copy[256];
    strcpy(input_copy,input_path);
    strcpy(output_copy,output_path);

    nary_pointer input = (nary_pointer) nary_search(input_copy);
    nary_pointer output = (nary_pointer) nary_search(output_copy);

    if(total_fdcount == (total_size * 1024)/BLOCK_SIZE) {
        printf("%s\n", ERR_VFS_COPYFILE_04); // "FILE_SYSTEM_FULL"
        return;
    }

    if(input == NULL) {
       printf("%s\n", ERR_VFS_COPYFILE_01); // "CANNOT_FIND_SOURCEFILE"
       return;
    }
    if(output == NULL) {
        printf("%s\n",ERR_VFS_COPYFILE_02); // "CANNOT_FIND_DESTINATIONPATH"
        return;
    }
    if(input->type == 'd') {
        printf("%s\n",ERR_VFS_COPYFILE_01); // "CANNOT_FIND_SOURCEFILE"
        return;
    }
    if(output->type == 'f') {
        printf("%s\n",ERR_VFS_COPYFILE_02); // "CANNOT_FIND_DESTINATIONPATH"
        return;
    }

    long int write_block_no = get_free_block();
    if(write_block_no == -1) {
    	printf("%s\n",ERR_VFS_COPYFILE_05); // "copyfile_FAILURE VFS_NOT_MOUNTED"
    	return;
    }

    // copy part
    FILE *ep = fopen(vfs_name,"r+");

    long int read_block_no = input->block_num;

    fseek(ep, sizeof(long int) + ((total_size * 1024 * sizeof(char)) / BLOCK_SIZE) +
          ((total_size * 1024 * sizeof(struct fd)) / BLOCK_SIZE), SEEK_SET);
	fseek(ep, write_block_no * BLOCK_SIZE, SEEK_CUR);

    fseek(vfs_ptr, sizeof(long int) + ((total_size * 1024 * sizeof(char)) / BLOCK_SIZE) +
          ((total_size * 1024 * sizeof(struct fd)) / BLOCK_SIZE), SEEK_SET);
	fseek(vfs_ptr, read_block_no * BLOCK_SIZE, SEEK_CUR);

    int size;
    fread(&size, sizeof(int), 1, vfs_ptr);
    fwrite(&size, sizeof(int), 1, ep);

    char *file_name, *token, *temp_output_path, rest[] = "a";
    strcpy(temp_output_path, output_path);
    
    while(rest != NULL) {
    	token = strtok_r(temp_output_path,"/",&rest);
    }
    int res = InsertIntoNArray(output_path, token, write_block_no, 'f');

    if(res == -1){
        printf("%s\n", ERR_VFS_COPYFILE_04);		// "FILE_SYSTEM_FULL"
        return;
    }
	
	// new code
	char* full_path = (char*)malloc(sizeof(char)*256);
	char* temp_ful_bst = (char*)malloc(sizeof(char)*256);
    full_path = strcpy(full_path, "root");
    full_path = strcat(full_path, output_path);
    int len = strlen(full_path);

    if(full_path[len - 1] == '/'){
        strncpy(temp_ful_bst, full_path, (strlen(full_path) -1));
    }
     
    int bst_res = insert_bst(temp_ful_bst);

    if(bst_res == -1){
        printf("%s\n", ERR_VFS_COPYFILE_04);		// "FILE_SYSTEM_FULL"
        return;
    }
    
    // ends
    
   while(size-- != 0) {
        ch = getc(vfs_ptr);
        putc(ch,ep);
    }

   printf("%s\n", SUCC_VFS_COPYFILE);			// "copyfile_SUCCESS"
}

void mount_vfs(char* name) {

    if(file_exists(name) == 0){
        printf("%s\n",ERR_VFS_MOUNT_01);        // DATA_FILE_NOT_FOUND
        return;
    }

    strcpy(vfs_name, name);
	vfs_ptr = fopen(vfs_name,"r+");

	if(vfs_ptr == NULL) {
		printf("%s\n", ERR_VFS_MOUNT_02);       // CANNOT_READ_FROM_FILE
		return;
	}

	fread(&total_size, sizeof(long int), 1, vfs_ptr);

	free_list = (char *) malloc((sizeof(char) * total_size * 1024) / BLOCK_SIZE);
    fread(free_list, (sizeof(char) * total_size * 1024) / BLOCK_SIZE, 1, vfs_ptr);

    fd_array = (struct fd *) malloc((sizeof(struct fd) * total_size * 1024) / BLOCK_SIZE);
    fread(fd_array, (sizeof(struct fd) * total_size * 1024) / BLOCK_SIZE, 1, vfs_ptr);

    build_dir_struct();
    rebuild_dir_struct();
    if(bst_root == NULL || root_dir == NULL){
        printf("%s\n", ERR_VFS_MOUNT_03);
        return;
    }

    is_vfsmounted = 1;

    printf("%s\n", SUCC_VFS_MOUNT);				// "mountvfs_SUCCESS"
}

void unmount_vfs(char *name) {

    if(vfs_ptr == NULL){
        printf("%s\n", ERR_VFS_UNMOUNT_01 );    // DATA_FILE_NOT_FOUND
        return;
    }

    form_fd_array();

    fseek(vfs_ptr, 0, SEEK_SET);
    fwrite(&total_size, sizeof(long int), 1, vfs_ptr);
    fwrite(free_list, (sizeof(char) * total_size * 1024) / BLOCK_SIZE, 1, vfs_ptr);
    fwrite(fd_array, (sizeof(struct fd) * total_size * 1024) / BLOCK_SIZE, 1, vfs_ptr);   

    if(vfs_ptr != NULL) fclose(vfs_ptr);

    is_vfsmounted=0;

    printf("%s\n",SUCC_VFS_UNMOUNT);		// "unmountvfs_SUCCESS"
}

void delete_dir(char* name){

    char *full_path = (char *)malloc(sizeof(char) * 256);
    int nary_res, bst_res, len;

    strcpy(full_path, "root");

    if(name[0] != '/'){
        strcpy(full_path, "/");
    }

    char *temp_name = (char *)malloc(sizeof(char) * 256);
    strcpy(temp_name, name);
    if(name[strlen(name)-1] == '/'){
    	// printf();
        strncpy(temp_name, name, strlen(name)-1);
    }
    name = temp_name;

    strcat(full_path, name);

    nary_res = nary_delete(name);

    if(nary_res == 0){ // Invalid path
        printf("%s\n",ERR_VFS_DELETEDIR_01);        // CANNOT_FIND_SPECIFIED_DIR
        return;
    }
    else if(nary_res == -1){ // directory not empty.
        printf("%s\n",ERR_VFS_DELETEDIR_02);        // ERR_VFS_DELETEDIR_02 "DIRECTORY_IS_NOT_EMPTY
        return;
    }else{
        printf("%s\n", SUCC_VFS_DELETEDIR); 		//deletedir_SUCCESS"
        return;
    }

    bst_delete(full_path);

    printf("%s\n", SUCC_VFS_DELETEDIR); 		//deletedir_SUCCESS"

}

void delete_file(char *name) {

    char full_path[256];
    int nary_res, bst_res, len;

    strcpy(full_path, "root");

    if(name[0] != '/'){
        strcpy(full_path, "/");
    }

    strcat(full_path, name);

    nary_res = nary_delete(name);


    if(nary_res == 0){ // Invalid path
        printf("%s\n",ERR_VFS_REMOVEFILE_01);
        return;
    }
    else if(nary_res == -1){ // directory not empty.
        printf("%s\n",ERR_VFS_REMOVEFILE_01);
        return;
    }
    bst_delete(full_path);

    printf("%s\n", SUCC_VFS_REMOVEFILE);			// "removefile_SUCCESS"
}

void ls(char *path, int rec_flag, char *save_path) {

   int res = list_files(path,rec_flag,save_path);
   if(res == 1){
        printf("%s\n", SUCC_VFS_LISTDIR);		// "listdir_SUCCESS"
   }
}

void search(char* file_path){

    char* searchOutput = bst_search(file_path);
}

void export_file(char *internal, char *external) {
    nary_pointer ip = (nary_pointer) nary_search(internal);
    char ch;

    if(ip == NULL) {
        return;
    }
    if(ip->type == 'd') {
        return;
    }


    FILE *ep = fopen(external,"w");
    long int block = ip->block_num;

    fseek(vfs_ptr, sizeof(long int) + ((total_size * 1024 * sizeof(char)) / BLOCK_SIZE) +
          ((total_size * 1024 * sizeof(struct fd)) / BLOCK_SIZE), SEEK_SET);
	fseek(vfs_ptr, block * BLOCK_SIZE, SEEK_CUR);

    while((ch = getc(vfs_ptr)) != '~') {

        fputc(ch,ep);
    }

    if(ep != NULL) fclose(ep);
}

void export_binary_file(char *internal, char *external, int flag) {
    nary_pointer ip = (nary_pointer) nary_search(internal);
    char ch;

    if(flag == 0) {
        if(ip == NULL) {
            printf("%s\n",ERR_VFS_LISTFILE_01); // "SOURCE_FILE_PATH_NOT_FOUND"
            return;
        }
        if(ip->type == 'd') {
            printf("%s\n",ERR_VFS_LISTFILE_02); // "NOT_A_TEXT_FILE"
            return;
        }
        if(internal[strlen(internal)-4] != '.' || internal[strlen(internal)-3] != 't'|| internal[strlen(internal)-2] != 'x' ||
           internal[strlen(internal)-1] != 't') {
            printf("%s\n",ERR_VFS_LISTFILE_02); // "NOT_A_TEXT_FILE"
            return;
        }
    }
    else if(flag == 1) {
        if(ip == NULL) {
            printf("%s\n",ERR_VFS_EXPORTFILE_01); // "CANNOT_FIND_SOURCEFILE"
            return;
        }
        if(ip->type == 'd') {
            printf("%s\n",ERR_VFS_EXPORTFILE_03); // "CANNOT_EXPORT_DIR"
            return;
        }
    }


    FILE *ep = fopen(external,"w");
    if(flag == 0) {
        if(ferror(ep) != 0) {
            printf("%s\n",ERR_VFS_LISTFILE_03); // "CANNOT_CREATE_OUTPUTFILE"
            return;
        }
    }
    else if(flag == 1) {
        if(ferror(ep) != 0) {
            printf("%s\n",ERR_VFS_EXPORTFILE_02); // "CANNOT_CREATE_OUTPUTFILE"
            return;
        }
    }

    FILE *binary_vfs_ptr = fopen(vfs_name,"r+");

    long int block = ip->block_num;

    fseek(binary_vfs_ptr, sizeof(long int) + ((total_size * 1024 * sizeof(char)) / BLOCK_SIZE) +
          ((total_size * 1024 * sizeof(struct fd)) / BLOCK_SIZE), SEEK_SET);
	fseek(binary_vfs_ptr, block * BLOCK_SIZE, SEEK_CUR);

    int size;
    fread(&size, sizeof(int), 1, binary_vfs_ptr);
    
    while(size-- != 0) {
        ch = getc(binary_vfs_ptr);
        putc(ch,ep);
    }

    if(binary_vfs_ptr != NULL) fclose(binary_vfs_ptr);
    if(flag == 0) 
    	printf("%s\n", SUCC_VFS_LISTFILE);			// "listfile_SUCCESS"
    else if(flag == 1) 
    	printf("%s\n",SUCC_VFS_EXPORTFILE);			// "exportfile_SUCCESS"
}

void move_file(char *input_path, char *output_path) {
     nary_pointer input,output;

     input = (nary_pointer) nary_search(input_path);
     output = (nary_pointer) nary_search(output_path);

     if(input == NULL) {
       printf("%s\n", ERR_VFS_MOVEFILE_01);		// "CANNOT_FIND_SOURCEFILE"
       return;
     }

     if(output == NULL) {
       printf("%s\n",ERR_VFS_MOVEFILE_02);		// "CANNOT_FIND_DESTINATION_PATH"
       return;
     }


     int res = move_nodes(input_path, output_path, 'f');
     
     if(res == 0){
     	printf("%s\n", ERR_VFS_MOVEFILE_01);	// "CANNOT_FIND_SOURCEFILE"
     	return;
     }
     
      // new code
     char* full_path = (char*)malloc(sizeof(char)*256);
     char* temp_bst_path = (char*)malloc(sizeof(char)*256);
     
     // delete source
     strcpy(full_path, "root");

    if(input_path[0] != '/'){
        strcat(full_path, "/");
    }
    
    strcat(full_path, input_path);
    strcpy(temp_bst_path, full_path);
    if(input_path[strlen(input_path)] == '/'){
    	strncpy(temp_bst_path, full_path, strlen(full_path) -1);
    }
    
    bst_delete(temp_bst_path);
    
    // insert at destination
      strcpy(full_path, "root");

    if(output_path[0] != '/'){
        strcat(full_path, "/");
    }
    
    strcat(full_path, output_path);
    strcpy(temp_bst_path, full_path);
    if(output_path[strlen(output_path)] == '/'){
    	strncpy(temp_bst_path, full_path, strlen(full_path) -1);
    }
    
    insert_bst(temp_bst_path);    
         
    // ends
         
     printf("%s\n", SUCC_VFS_MOVEFILE);			// "movefile_SUCCESS");
}

void move_directory(char *input_path, char *output_path) {

     nary_pointer input,output;

     input = (nary_pointer) nary_search(input_path);
     output = (nary_pointer) nary_search(output_path);

     if(input == NULL) {
       printf("%s\n", ERR_VFS_MOVEDIR_01);
       return;
     }

     if(output == NULL) {
       printf("%s\n",ERR_VFS_MOVEDIR_02);
       return;
     }

     if(input->type == 'f'){
        printf("%s\n",ERR_VFS_MOVEDIR_04); // "SOURCE_CANNOT_BE_FILE"
        return;
     }
     if(output->type == 'f'){
        printf("%s\n",ERR_VFS_MOVEDIR_07); // "DESTINATION_CANNOT_BE_FILE"
        return;
     }
     if(output->parent == input) {
        printf("%s\n",ERR_VFS_MOVEDIR_06); // "CANNOT_MOVE_PARENT_TO_CHILD_DIR"
        return;
     }
     if(input->parent == output) {
        printf("%s\n", ERR_VFS_MOVEDIR_05); // "DESTINATION_ALREADY_HAS_SOURCE_DIR"
        return;
     }
    int res = move_nodes(input_path, output_path, 'd');
    if(res == 0){//printf("File system empty.\n");
    	printf("%s\n",ERR_VFS_MOVEDIR_01);	// "CANNOT_FIND_SPECIFIED_SOURCEDIR" );
    	return;	
    }
    else if(res == -1){ // printf("Cannot insert below a file.\n");
    	printf("%s\n", ERR_VFS_MOVEDIR_07);	// "DESTINATION_CANNOT_BE_FILE");
    	return;
    }
    
    // new code
     char* full_path = (char*)malloc(sizeof(char)*256);
     char* temp_bst_path = (char*)malloc(sizeof(char)*256);
     
     // delete source
     strcpy(full_path, "root");

    if(input_path[0] != '/'){
        strcat(full_path, "/");
    }
    
    strcat(full_path, input_path);
    strcpy(temp_bst_path, full_path);
    if(input_path[strlen(input_path)] == '/'){
    	strncpy(temp_bst_path, full_path, strlen(full_path) -1);
    }
    
    bst_delete(temp_bst_path);
    
    // insert at destination
      strcpy(full_path, "root");

    if(output_path[0] != '/'){
        strcat(full_path, "/");
    }
    
    strcat(full_path, output_path);
    strcpy(temp_bst_path, full_path);
    if(output_path[strlen(output_path)] == '/'){
    	strncpy(temp_bst_path, full_path, strlen(full_path) -1);
    }
    
    insert_bst(temp_bst_path);    
         
    // ends
    
    printf("%s\n",SUCC_VFS_MOVEDIR);		// "movedir_SUCCESS"
}

void search_files(char* input_name, char* output_file){

    FILE *fptr=fopen(output_file,"w");

	if(fptr ==NULL)
    {
        printf("%s\n",ERR_VFS_SEARCHFILE_03);       // "SEARCH_RESULT_UNABLE_TO_OPEN_OUTPUT_FILE"
        return;
    }

    char *search_output = bst_search(fptr, input_name);
    fprintf(fptr,"%s\n",search_output);

    if(fptr != NULL) fclose(fptr);

    printf("%s\n", SUCC_VFS_SEARCHFILE);			// "searchfile_SUCCESS"
}
